from Types import *
import json

AOF_VERSION = 1
DATA_BEGIN_INDEX = 2
KEY_DATA = 'd'

# 生成AOF記錄的函數：參數與DB類中對應方法的參數一致，把參數轉換成列表(aofRecord)并返回
# 解析AOF記錄的函數：返回值為對應DB類方法的參數列表，是列表類型

def toAOFaofString(aofRecordType, aofRecord):
    '''所有生成AOF記錄函數的通用操作
    aofRecordType: 要生成的AOF記錄的類型
    aofRecord: 轉換成列表的數據，要求列表的每一項應該是基本類型或者可以轉換為JSON'''
    if type(aofRecord) != list:
        raise ValueError()
    tmp = aofRecord
    aofRecord = [AOF_VERSION, aofRecordType]
    aofRecord.extend(tmp)
    jsObj = {}
    jsObj[KEY_DATA] = aofRecord
    aofStr = json.dumps(jsObj, separators=(',',':')) + '\n'
    return aofStr

def AddIncomeRecordToAOFRecord(record):
    aofRecord = []
    aofRecord.append(record.time)
    aofRecord.append(record.accountId)
    aofRecord.append(record.cat1Id)
    aofRecord.append(record.amount)
    aofRecord.append(record.description)
    return aofRecord

def AOFRecordToAddIncomeRecord(aofRecord):
    record = IncomeRecord()
    record.time = aofRecord[0]
    record.accountId = aofRecord[1]
    record.cat1Id = aofRecord[2]
    record.amount = aofRecord[3]
    record.description = aofRecord[4]
    return [record]

def AddPaymentRecordToAOFRecord(record):
    aofRecord = []
    aofRecord.append(record.time)
    aofRecord.append(record.accountId)
    aofRecord.append(record.cat1Id)
    aofRecord.append(record.cat2Id)
    aofRecord.append(record.amount)
    aofRecord.append(record.description)
    return aofRecord

def AOFRecordToAddPaymentRecord(aofRecord):
    record = PaymentRecord()
    record.time = aofRecord[0]
    record.accountId = aofRecord[1]
    record.cat1Id = aofRecord[2]
    record.cat2Id = aofRecord[3]
    record.amount = aofRecord[4]
    record.description = aofRecord[5]
    return [record]

def AddTransferrecordToAOFRecord(record):
    aofRecord = []
    aofRecord.append(record.time)
    aofRecord.append(record.amount)
    aofRecord.append(record.cat1Id)
    aofRecord.append(record.srcAccountId)
    aofRecord.append(record.dstAccountId)
    aofRecord.append(record.description)
    return aofRecord

def AOFRecordToAddTransferRecord(aofRecord):
    record = TransferRecord()
    record.time = aofRecord[2]
    record.amount = aofRecord[3]
    record.cat1Id = aofRecord[4]
    record.srcAccountId = aofRecord[5]
    record.dstAccountId = aofRecord[6]
    record.desctiption = aofRecord[7]
    return [record]
    
def DeleteIncomeRecordToAOFRecord(recordId):
    return [recordId]

def AOFRecordToDeleteIncomeRecord(aofRecord):
    return [aofRecord[0]]
    
def DeletePaymentRecordToAOFRecord(recordId):
    return [recordId]

def AOFRecordToDeletePaymentRecord(aofRecord):
    return [aofRecord[0]]

def DeleteTransferRecordToAOFRecord(recordId):
    return [recordId]

def AOFRecordToDeleteTransferRecord(aofRecord):
    return [aofRecord[0]]

def SetBudgetToAOFRecord(budgetList):
    return [budgetList]

def AOFRecordToSetBudget(aofRecord):
    return [aofRecord[0]]

def ParseAOFRecord(aofRecord):
    '''解析一条AOF记录，返回對應數據庫操作的类型和參數列表
    可以支持DB類的方法有多個參數的情況'''
    jsObj = json.loads(aofRecord)
    version = jsObj[KEY_DATA][0]
    recordType = jsObj[KEY_DATA][1]
    if recordType == AOFRecordType.AddIncomeRecord:
        args = AOFRecordToAddIncomeRecord(jsObj[KEY_DATA][DATA_BEGIN_INDEX:])
    elif recordType == AOFRecordType.AddPaymentRecord:
        args = AOFRecordToAddPaymentRecord(jsObj[KEY_DATA][DATA_BEGIN_INDEX:])
    elif recordType == AOFRecordType.AddTransferRecord:
        args = AOFRecordToAddTransferRecord(jsObj[KEY_DATA][DATA_BEGIN_INDEX:])
    elif recordType == AOFRecordType.DeleteIncomeRecord:
        args = AOFRecordToDeleteIncomeRecord(jsObj[KEY_DATA][DATA_BEGIN_INDEX:])
    elif recordType == AOFRecordType.DeletePaymentReocrd:
        args = AOFRecordToDeletePaymentRecord(jsObj[KEY_DATA][DATA_BEGIN_INDEX:])
    elif recordType == AOFRecordType.DeleteTransferRecord:    
        args = AOFRecordToDeleteTransferRecord(jsObj[KEY_DATA][DATA_BEGIN_INDEX:])
    elif recordType == AOFRecordType.SetBudget:
        args = AOFRecordToSetBudget(jsObj[KEY_DATA][DATA_BEGIN_INDEX:])
    else:
        raise ValueError('Unknow AOFRecordType: %d'%(recordType))
    return (recordType, args)
    